package com.dlc.felear.xiaoensale.helper;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.dlc.felear.xiaoensale.constant.Constant;
import com.dlc.felear.xiaoensale.entity.NextStep;
import com.dlc.felear.xiaoensale.factory.CmdList;
import com.dlc.felear.xiaoensale.utils.RecordLog;

import java.util.ArrayList;
import java.util.concurrent.ScheduledExecutorService;

public class GuotiHelper implements Handler.Callback {
    private static final String TAG = "GuotiHelper";
    private static final int WHAT_FW = 9277;
    private static final int WHAT_CLOSE = 9247;
    private final int IO_CLOSE_VALUE = 0;
    private final int IO_OPEN_VALUE = 0xff;
    private int xgDelay = 0;
    private int gtCurrentPosition = 2;
    private boolean crosssSensor = false;
    private IoOutHelper ioOutHelper;
    private IoInputHelper inputHelper;
    private String serialNum;
    private byte io_gt_base = 14;
    private byte io_chuifeng = 26;
    private byte io_o_choufeng = 27;
    private byte io_o_gt_zz = 1;
    private byte io_o_gt_fz = 0;
    private byte io_o_xg_shui = 28;
    private JiaoBanHelper jiaoBanHelper;
    private LiaoHeHelper liaoHeHelper;
    private boolean xgStatus = false;
    private boolean cgStatus = false;
    private boolean fwFlag = false;
    private boolean isJgttl = false;
    private final long gt_delay_init = 5000;
    private final byte io_i_gt_0 = 0;
    private final byte io_i_gt_1 = 1;
    private final byte io_i_gt_2 = 2;
    private final byte io_i_gt_3 = 3;
    private final byte io_i_gt_4 = 4;
    private Handler handler;
    private ScheduledExecutorService scheduledThreadPool;
    private ArrayList<NextStep> nextSteps;
    private Session session;

    private void setBooleanValue(boolean xgStatus, boolean cgStatus, boolean isJgttl, boolean fwFlag) {
        this.xgStatus = xgStatus;
        this.cgStatus = cgStatus;
        this.fwFlag = fwFlag;
        this.isJgttl = isJgttl;
        crosssSensor = false;
    }


    public GuotiHelper(Context context,IoOutHelper ioOutHelper, IoInputHelper inputHelper,
                       String serialNum, ScheduledExecutorService scheduledThreadPool,
                       JiaoBanHelper jiaoBanHelper, LiaoHeHelper liaoHeHelper) {
        this.ioOutHelper = ioOutHelper;
        this.inputHelper = inputHelper;
        this.jiaoBanHelper = jiaoBanHelper;
        this.liaoHeHelper = liaoHeHelper;
        this.serialNum = serialNum;
        nextSteps = new ArrayList<>();
        this.scheduledThreadPool = scheduledThreadPool;
        handler = new Handler(this);
        session=Session.getSession();
        gtCurrentPosition=session.getInt(TAG,2);
    }


    /**
     * 打开io 并延迟关闭
     *
     * @param num
     * @param delay
     */
    private void openIoAndDelayClose(byte num, long delay) {
        controlOutputIo(num, IO_OPEN_VALUE);
        sendDelayCloseIoMsg(WHAT_CLOSE, num, delay);
    }


    /**
     * 锅体停止转动
     */
    public void stopGtAction() {
        log("锅体停止转动", 0);
        controlOutputIo(io_o_gt_fz, 0);
        controlOutputIo(io_o_gt_zz, 0);
    }

    /**
     * 洗锅动作
     *
     * @param second
     */
    public void xiguoAction(final int second) {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                if (liaoHeHelper.isBottomPosition() && !liaoHeHelper.allGzCloseStatus()) {
                    log("格子门没有关好，不能执行洗锅动作", 1);
                    return;
                }
                setBooleanValue(true, false, false, false);
                xgDelay = second * 1000;
                if (inputHelper.getIoStatus(io_i_gt_1) == 1) {
                    //锅体在洗锅的位置
                    log("锅体在洗锅的位置", 0);
                    startXgAction(xgDelay);
                } else {
                    //锅体不在洗锅的位置
                    log("锅体不在洗锅的位置,需转到洗锅的位置", 1);
                    gtFanzhuan(5000);
                }
            }
        });
    }

    /**
     * 锅体正转
     *
     * @param delay
     */
    private void gtZhengzhuan(long delay) {
        controlOutputIo(io_o_gt_zz, 0xFF);
        sendDelayCloseIoMsg(WHAT_CLOSE, io_o_gt_zz, delay);
    }

    /**
     * 锅体反转
     *
     * @param delay
     */
    private void gtFanzhuan(long delay) {
        controlOutputIo(io_o_gt_fz, 0xFF);
        sendDelayCloseIoMsg(WHAT_CLOSE, io_o_gt_fz, delay);
    }

    /**
     * 洗锅动作
     *
     * @param delay
     */
    private void startXgAction(final int delay) {
        stopGtAction();
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    if (xgStatus && inputHelper.getIoStatus(io_i_gt_3) == 1) {
                        //锅体在洗锅的位置，直接打开水龙头和搅拌
                        log("打开水龙头和搅拌", 0);
                        openXgShui(delay - 1000);
                        jiaoBanHelper.xiguoJiaoban(delay);
                        Thread.sleep(delay);
                        jiaoBanHelper.immediatelyStop();
                        Thread.sleep(3000);
                        controlOutputIo(io_o_gt_fz, IO_OPEN_VALUE, 10000);
                    }
                } catch (Exception e) {

                }
            }
        });
    }

    private void paishuiXgAction(final int delay) {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    if (xgStatus) {
                        //锅体在洗锅的位置，直接打开水龙头和搅拌
                        log("洗锅倒水", 0);
                        jiaoBanHelper.xiguoJiaoban(delay);
                        Thread.sleep(delay);
                        jiaoBanHelper.immediatelyStop();
                        Thread.sleep(1000);
                        setBooleanValue(false, false, false, true);
                        gtFw();
                    }
                } catch (Exception e) {

                }
            }
        });
    }


    private void openXgShui(long delay) {
        controlOutputIo(io_o_xg_shui, 0xFF, delay);
    }

    /**
     * 复位
     */
    public void gtFw() {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                setBooleanValue(false, false, false, true);
                if(gtCurrentPosition==2||inputHelper.getIoStatus(io_i_gt_2) == 1){
                    log("锅体已经在中间", 1);
                    return;
                }
                crosssSensor = true;
                log("锅体复位", 0);
                if (inputHelper.getIoStatus(io_i_gt_1) == 1 || inputHelper.getIoStatus(io_i_gt_0) == 1
                        || gtCurrentPosition == 0 || gtCurrentPosition == 1) {
                    gtFanzhuan(10000);
                    log("向内转回正", 0);
                } else if (inputHelper.getIoStatus(io_i_gt_3) == 1 || inputHelper.getIoStatus(io_i_gt_4) == 1
                        || gtCurrentPosition == 4 || gtCurrentPosition == 3) {
                    log("向外转回正", 0);
                    gtZhengzhuan(10000);
                }
            }
        });
    }

    /**
     * 位置检测
     *
     * @param num
     */
    public void sensorStatus(final byte num) {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                sensorStatusHandle(num);
            }
        });
    }

    /**
     * 传感器触发处理
     *
     * @param num
     */
    public void sensorStatusHandle(byte num) {
        if (num > 4) {
            return;
        }
        log("触发：num=" + num + " xgStatus=" + xgStatus + " isJgttl=" + isJgttl + " fwFlag=" + fwFlag +
                " cgStatus=" + cgStatus + " crosssSensor=" + crosssSensor, 0);
        gtCurrentPosition = num;
        savePosition(gtCurrentPosition);
        switch (num) {
            case 0:
                //出锅倒菜位置
                gtPsition_0();
                break;
            case 1:
                gtPsition_1();
                break;
            case 2:
                gtPsition_2();
                break;
            case 3:
                gtPosition_3();
                break;
            case 4:
                //倒水位置
                stopGtAction();
                crosssSensor = true;
                if (fwFlag) {
                    gtZhengzhuan(6000);
                    return;
                }
                if (xgStatus) {
                    paishuiXgAction(5000);
                }
                break;
        }
    }

    private void gtPsition_0() {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    stopGtAction();
                    if (cgStatus) {
                        jiaoBanHelper.chuguoJiaoban(10000);
                        jiaoBanHelper.stopJiaobanDelay(10000);
                    }
                    Thread.sleep(10000);
                    setBooleanValue(false, false, false, false);
                } catch (Exception e) {

                }
            }
        });
    }

    private void gtPsition_1() {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    if (fwFlag) {
                        gtFanzhuan(3000);
                        return;
                    }
                    if (isJgttl) {
                        stopGtAction();
                        gtFanzhuan(5000);
                    }
                } catch (Exception e) {

                }
            }
        });
    }

    private void gtPsition_2() {
        //锅体在正中间
        if (fwFlag) {
            jiaoBanHelper.recoverSpeed();
            setBooleanValue(false, false, false, false);
            stopGtAction();
        }
    }

    private void gtPosition_3() {
        if (fwFlag) {
            gtZhengzhuan(3000);
            return;
        }

        if (xgStatus && !crosssSensor) {
            stopGtAction();
            startXgAction(xgDelay);
        } else if (isJgttl && !crosssSensor) {
//            stopGtAction();
//            handlerGttl();
        }
    }

    /**
     * 加固体调料
     */
    private void handlerGttl() {
        log("开始加固体调料:", 0);
        stopGtAction();
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                long temp = 0;
                if (!nextSteps.isEmpty()) {
                    for (NextStep nextStep : nextSteps) {
                        openIoAndDelayClose(nextStep.getNum(), nextStep.getDelayTime());
                        if (temp <= nextStep.getDelayTime()) {
                            temp = nextStep.getDelayTime();
                        }
                        nextSteps.remove(nextStep);
                    }
                }
                sendDelayCloseIoMsg(WHAT_FW, 0, temp + gt_delay_init);
            }
        });
    }

    /**
     * 加固体调料
     *
     * @param num
     * @param msce
     */
    public void jiaguti(final byte num, final long msce) {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                if (!liaoHeHelper.allGzCloseStatus()) {
                    log("格子门没有关好，不能执行加固体调料动作", 1);
                    return;
                }
                byte num1 = (byte) (io_gt_base + num);
                setBooleanValue(false, false, true, false);
                jiaoBanHelper.jiangsu((byte) 1);

                log("加固体调料:num=" + num + " 时间：" + msce + "毫秒", 0);
                controlOutputIo(io_chuifeng, IO_OPEN_VALUE);
                if (ioOutHelper.getIoStatus(num) == 0) {
                    log("正在加固提料", 0);
                    openIoAndDelayClose(num1, msce);
                    sendDelayCloseIoMsg(WHAT_FW, 0, msce + gt_delay_init);
                    controlOutputIo(io_chuifeng, 0, msce + gt_delay_init);
                }
            }
        });
    }


    /**
     * 出锅逻辑
     */
    public void chuguo() {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                if (liaoHeHelper.isBottomPosition() && !liaoHeHelper.allGzCloseStatus()) {
                    log("料盒格子门没有关好，不能执行加出锅倒菜动作", 1);
                    return;
                }
                setBooleanValue(false, true, false, false);
                log("符合出锅条件，开始倒菜出锅", 0);
                if (inputHelper.getIoStatus(io_i_gt_0) != 1) {
                    gtZhengzhuan(8000);
                } else {
                    log("锅体未检测到第3个传感器位置", 1);
                }
            }
        });
    }


    @Override
    public boolean handleMessage(Message msg) {
        if (WHAT_CLOSE == msg.what) {
            controlOutputIo((byte) msg.arg1, IO_CLOSE_VALUE);
        } else if (WHAT_FW == msg.what) {
            gtFw();
        }
        return false;
    }


    private void log(String msg, int level) {
        if (level == 1) {
            RecordLog.getInstance().saveLog(msg);
        }
        Log.e(TAG, msg);
    }

    /**
     * 抽风开
     *
     * @param value
     */
    public void choufeng(final byte value) {
        log("抽风:" + value, 0);
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                if (value == 0) {
                    controlOutputIo(io_chuifeng, IO_CLOSE_VALUE);
                    controlOutputIo(io_o_choufeng, IO_CLOSE_VALUE);
                } else {
                    controlOutputIo(io_chuifeng, IO_OPEN_VALUE);
                    controlOutputIo(io_o_choufeng, IO_OPEN_VALUE);
                }
            }
        });
    }

    /**
     * 延迟关闭
     *
     * @param num
     * @param time
     */
    private void sendDelayCloseIoMsg(int what, int num, long time) {
        Message message = new Message();
        message.what = what;
        message.arg1 = num;
        message.arg2 = num >= 26 ? 3 : 2;
        handler.sendMessageDelayed(message, time);
    }

    /**
     * io状态控制
     *
     * @param num
     * @param value
     */
    private void controlOutputIo(final byte num, final int value) {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                if (num >= 26) {
                    sendCmd(serialNum, CmdList.controlOutputIo(3, num - 26, value));
                } else {
                    sendCmd(serialNum, CmdList.controlOutputIo(2, num, value));
                }
            }
        });
    }

    public void closeAction() {
        fwFlag = true;
        controlOutputIo(io_o_choufeng, IO_CLOSE_VALUE, 10000);
        controlOutputIo(io_chuifeng, IO_CLOSE_VALUE);
        //关闭固体电机
        for (byte i = io_gt_base; i < io_gt_base + 5; i++) {
            controlOutputIo(i, IO_CLOSE_VALUE);
        }
    }

    /**
     * 打开IO 再延迟关闭
     *
     * @param num
     * @param value
     * @param delayclose
     */
    public void controlOutputIo(byte num, int value, long delayclose) {
        controlOutputIo(num, value);
        sendDelayCloseIoMsg(WHAT_CLOSE, num, delayclose);
    }

    private void sendCmd(String serialNo, byte[] data) {
        ioOutHelper.addCmdToQueque(data);
    }

    public String getErrorMsg() {
        if (inputHelper.getIoStatus(io_i_gt_2) != 1) {
            return "锅体位置异常";
        }
        return "";
    }

    public byte getPosition(byte num) {
        if (inputHelper.getIoStatus(num) == 1) {
            return 1;
        }
        return 0;
    }


    public void stopActionDelay() {
        setBooleanValue(false, false, false, true);
    }

    private void savePosition(int position){
        session.setInt(TAG,position);
    }
}
